% function computes the matrix of spikes for given connectome involved by
% input signals. Results of this function is: output - vector of computated
% output from connectome and the matrixOfSpikes which presents the "map"
% of connectome's spiking - present the matrix of which neuron spiked in
% connectome
function [output, matrixOfSpikes, usedInput] = computeSpikesMatrix(obj, input)

    if (size(input) ~= obj.inputSize)
        disp('Error! Incorrect size of input');
        return 
    end
    usedInput = zeros(obj.maximalNumberOfNeuronsInLayer,1);

    matrixOfSpikes = zeros(obj.maximalNumberOfNeuronsInLayer, obj.numberOfLayers+2);
    
    for i=1:obj.inputSize
        receptor = getNeuron(obj, i, 0);
        if(input(i) > receptor.threshold)
            matrixOfSpikes(i,1) = 1;
            usedInput(i) = 1;
            lockSynapsesFromNeuron(obj,i,0);
        else
            matrixOfSpikes(i,1) = 0;
            usedInput(i) = 0;
        end
    end


    % compute which neurons spike (we fill 1th - nth column of
    % matricOfSpikes + (n+1)th layer - which tells which effectors 
    % spikes)
    for i=1:obj.numberOfLayers+1       % for each layers we have to 
                                     % generate vector of spikes that
                                     % come to the next layer and 
                                     % also to the matirxOfSpikes  
        usedOutput = zeros(obj.maximalNumberOfNeuronsInLayer,1);
        if (i <= obj.numberOfLayers)
            
            % Checks every neuron in HIDDEN layers if they spike or not
            for j=1:obj.neuronInLayerVector(i)%numberOfNeuronsInLayer % for each neuron we computes 
                                           % if it spike basing on 
                                           % the signal from previous
                                           % layer (or from input -
                                           % for first layer)
                neuronIn = getNeuron(obj,j,i);
                value = 0;
                if(i==1)
                    for k=1:obj.inputSize    % for each neuron
                                                      % in layer we
                                                      % have to sum
                                                      % weighted input
                                                      % from previous
                                                      % layer
                        synapse = getSynapse(obj,k,0,j,1);
                        value = value + passSignalThroughSynapse(synapse,usedInput(k));
                    end
                else
                    for k=1:obj.neuronInLayerVector(i-1) % for each neuron
                                                      % in layer we
                                                      % have to sum
                                                      % weighted input
                                                      % from previous
                                                      % layer
                        synapse = getSynapse(obj,k,i-1,j,i);
                        value = value + passSignalThroughSynapse(synapse,usedInput(k));
                    end
                end
                if(value > neuronIn.threshold)       % we have to check
                                                 % if sum is over
                                                 % the threshold if
                                                 % "yes" we this
                                                 % neuron spikes
                    usedOutput(j) = 1;
                    lockSynapsesFromNeuron(obj,i,j); % if neuron spikes
                                                     % we lock the
                                                     % synapse from
                                                     % this neuron for
                                                     % defined period
                                                     % of time.
                else
                    usedOutput(j) = 0;
                end
            end
        else
            
            % Checks every neuron in LAST layer if they spike or not
            for j=1:obj.outputSize %numberOfNeuronsInLayer % for each neuron we computes
                                           % if it spike basing on 
                                           % the signal from previous
                                           % layer (or from input -
                                           % for first layer)
                neuronIn = getNeuron(obj,j,i);
                value = 0;
                for k=1:obj.neuronInLayerVector(i-1) % for each neuron
                                                      % in layer we
                                                      % have to sum
                                                      % weighted input
                                                      % from previous
                                                      % layer
                   synapse = getSynapse(obj,k,i-1,j,i);
                   value = value + passSignalThroughSynapse(synapse,usedInput(k));
                end

                if(value > neuronIn.threshold)       % we have to check
                                                     % if sum is over
                                                     % the threshold if
                                                     % "yes" we this
                                                     % neuron spikes
                    usedOutput(j) = 1;
                    lockSynapsesFromNeuron(obj,i,j); % if neuron spikes
                                                     % we lock the
                                                     % synapse from
                                                     % this neuron for
                                                     % defined period
                                                     % of time.
                else
                    usedOutput(j) = 0;
                end
            end
        end
        usedInput = usedOutput;
        matrixOfSpikes(1:size(usedOutput),i+1) = usedOutput';
    end
    output = usedOutput';
end